﻿using Sgr.Data;
using Sgr.DataCategories.Domain.DataCategoryItem;
using Sgr.Domain.Uow;
using Sgr.Utilities;
using System.Text.Json;

namespace Sgr.DataCategories.Infrastructure.Sead
{
    public class DataCategoryDataBaseInitialize : IDataBaseInitialize
    {
        private readonly IDataCategoryItemManage _dataCategoryItemManage;
        private readonly IDataCategoryItemRepository _dataCategoryItemRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly ILogger<DataCategoryDataBaseInitialize> _logger;

        public DataCategoryDataBaseInitialize(
             IDataCategoryItemManage dataCategoryItemManage,
             IDataCategoryItemRepository dataCategoryItemRepository,
             IUnitOfWorkManager unitOfWorkManager,
             ILogger<DataCategoryDataBaseInitialize> logger)
        {
            _dataCategoryItemManage = dataCategoryItemManage;
            _dataCategoryItemRepository = dataCategoryItemRepository;
            _unitOfWorkManager = unitOfWorkManager;
            _logger = logger;
        }

        /// <summary>
        /// 获取初始化执行顺序，值越大越靠后执行
        /// </summary>
        public int Order => 888;

        public async Task Initialize()
        {
            try
            {
                // 检查数据字典表是否已存在数据
                var count = await _dataCategoryItemRepository.CountAsync();
                if (count > 0)
                {
                    return;
                }

                // 构建数据字典配置文件路径
                var jsonPath = Path.Combine(LocalFileHelper.GetApplicationDirectory(), "Sead", "system_dict.json");
                if (!File.Exists(jsonPath))
                {
                    _logger.LogWarning("未找到数据字典配置文件: {Path}", jsonPath);
                    return;
                }

                // 加载数据字典配置
                DictConfigRoot? dictConfig = await LoadDictConfigRootFromJson(jsonPath);
                if (dictConfig?.Dicts == null || dictConfig.Dicts.Count == 0)
                {
                    return;
                }

                // 递归创建数据字典
                foreach (var dictItem in dictConfig.Dicts)
                {
                    await CreateDictRecursively(dictItem, null);

                    _logger.LogInformation($"写入系统数据字典项 {dictItem.Name}...");
                }
                _logger.LogInformation("系统数据字典初始化完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "数据字典初始化过程中发生异常");
            }
        }

        /// <summary>
        /// 创建单个数据字典项
        /// </summary>
        private async Task<DataCategoryItem?> CreateDictItem(
            string name,
            string value,
            string? remarks,
            string categoryTypeCode,
            int orderNumber,
            bool isEditable,
            long? parentId)
        {
            // 创建字典项
            var dictItem = await _dataCategoryItemManage.CreateNewAsync(
                name: name,
                value: value,
                remarks: remarks,
                categoryTypeCode: categoryTypeCode,
                orderNumber: orderNumber,
                isEditable: isEditable,
                parentId: parentId
            );

            await _dataCategoryItemRepository.InsertAsync(dictItem);

            _logger.LogInformation("字典项创建成功: {CategoryType} - {Name} ({Value})",
                categoryTypeCode, name, value);

            return dictItem;
        }

        /// <summary>
        /// 递归创建数据字典
        /// </summary>
        private async Task CreateDictRecursively(DictItem dictItem, long? parentId)
        {
            using var uow = _unitOfWorkManager.Begin(requiresNew: true);
            try
            {
                // 创建当前字典项
                var item = await CreateDictItem(
                    name: dictItem.Name,
                    value: dictItem.Code,
                    remarks: dictItem.Description,
                    categoryTypeCode: dictItem.Type,
                    orderNumber: dictItem.Order,
                    isEditable: dictItem.Editable,
                    parentId: parentId
                );

                // 递归创建子字典项
                if (item != null && dictItem.Children != null && dictItem.Children.Count > 0)
                {
                    foreach (var child in dictItem.Children)
                    {
                        // 设置子项的分类编码与父项相同
                        child.Type = dictItem.Type;
                        await CreateDictRecursively(child, item.Id);
                    }
                }

                await uow.CommitAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建数据字典项失败: {CategoryType} - {Name} ({Value})",
                    dictItem.Type, dictItem.Name, dictItem.Code);
                await uow.RollbackAsync();
            }
        }

        /// <summary>
        /// 从JSON文件加载数据字典配置
        /// </summary>
        /// <param name="jsonPath">JSON文件路径</param>
        /// <returns>数据字典配置根节点</returns>
        private async Task<DictConfigRoot?> LoadDictConfigRootFromJson(string jsonPath)
        {
            DictConfigRoot? dictConfig = null;
            try
            {
                var jsonContent = await File.ReadAllTextAsync(jsonPath);
                dictConfig = JsonHelper.DeserializeObject<DictConfigRoot>(jsonContent);
            }
            catch (JsonException ex)
            {
                _logger.LogError(ex, "数据字典配置文件解析失败: {Path}", jsonPath);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "读取数据字典配置文件时发生异常: {Path}", jsonPath);
            }

            return dictConfig;
        }

        #region 数据模型类

        /// <summary>
        /// 数据字典配置根节点
        /// </summary>
        private class DictConfigRoot
        {
            /// <summary>
            /// 数据字典分类列表
            /// </summary>
            public List<DictItem> Dicts { get; set; } = new();
        }

        /// <summary>
        /// 数据字典
        /// </summary>
        private class DictItem
        {
            /// <summary>
            /// 分类
            /// </summary>
            public string Type { get; set; } = string.Empty;

            /// <summary>
            /// 名称
            /// </summary>
            public string Name { get; set; } = string.Empty;

            /// <summary>
            /// 编码
            /// </summary>
            public string Code { get; set; } = string.Empty;

            /// <summary>
            /// 描述
            /// </summary>
            public string? Description { get; set; }

            /// <summary>
            /// 是否可编辑
            /// </summary>
            public bool Editable { get; set; } = true;

            /// <summary>
            /// 排序号
            /// </summary>
            public int Order { get; set; }

            /// <summary>
            /// 字典项列表
            /// </summary>
            public List<DictItem>? Children { get; set; }
        }

        #endregion 数据模型类
    }
}